package com.droid.customcalendar.cal.view;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.droid.customcalendar.R;
import com.droid.customcalendar.cal.model.MonthCalendarDataGenerator;
import com.droid.customcalendar.cal.view.MonthView.OnDateSelectedListener;
import com.droid.customcalendar.cal.view.adapter.MonthPagerAdapter;

public class CalendarView extends RelativeLayout {

	private static final short MONTHS_TO_DISPLAY = 24;

	private ViewPager pager;
	private Button next;
	private Button prev;
	private TextView title;
	private DayOfWeekView weekView;
	private MonthCalendarDataGenerator[] generators;
	private Locale locale;
	private OnDateSelectedListener dateSelectedListener;
	private MonthPagerAdapter adapter;
 
	public CalendarView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		locale = Locale.getDefault();
		initMonthGenerators();
		View view = inflateView(R.layout.calendar_view_layout);
		pager = (ViewPager) view.findViewById(R.id.pager);
		next = (Button) view.findViewById(R.id.nextMonth);
		prev = (Button) view.findViewById(R.id.prevMonth);
		title = (TextView) view.findViewById(R.id.titleMonth);
		weekView = (DayOfWeekView) findViewById(R.id.weekView);
		setupView();
	}

	private void initMonthGenerators() {
		generators = new MonthCalendarDataGenerator[MONTHS_TO_DISPLAY];
		for (int index = 0; index < MONTHS_TO_DISPLAY; index++) {
			generators[index] = createGenerator(index);
		}
	}

	protected MonthCalendarDataGenerator createGenerator(int position) {
		Calendar cal = Calendar.getInstance(locale);
		cal.add(Calendar.MONTH, position);
		return new MonthCalendarDataGenerator(cal.getTime(), locale);
	}

	private View inflateView(int layoutId) {
		Context context = getContext();
		LayoutInflater inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		return inflater.inflate(layoutId, this);
	}

	protected void setupView() {
		setButtonActions();
		int month = pager.getCurrentItem();
		updateCalendarHeader(month);
		setPagerAdapter();
		pager.setPageMargin(10); // TODO - replace with a dimen/attr value
		pager.setOnPageChangeListener(new CalendarMonthChangedListener());
		List<String> daysOfWeek = generators[0].getDays();
		weekView.setDays(daysOfWeek);
	}

	private void setButtonActions() {
		next.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				int crtIndex = pager.getCurrentItem() + 1;
				PagerAdapter adapter = pager.getAdapter();
				if (adapter != null && crtIndex <= adapter.getCount()) {
					goToMonth(crtIndex);
				}
			}
		});
		prev.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				int crtIndex = pager.getCurrentItem() - 1;
				if (crtIndex >= 0) {
					goToMonth(crtIndex);
				}
			}
		});
	}

	protected void updateMonthTitle(int index) {
		MonthCalendarDataGenerator g = generators[index];
		title.setText(g.getMonthName() + " " + String.valueOf(g.getYear()));
	}

	protected void updateCalendarHeader(int pos) {
		updateMonthTitle(pos);
		if (pos == 0) {
			prev.setVisibility(View.INVISIBLE);
		} else {
			prev.setVisibility(View.VISIBLE);
		}
		if (pos < generators.length - 1) {
			next.setVisibility(View.VISIBLE);
		} else {
			next.setVisibility(View.INVISIBLE);
		}
	}

	protected void setPagerAdapter() {
		adapter = new MonthPagerAdapter(generators);
		if (dateSelectedListener != null) {
			adapter.setOnDateSelectedListener(dateSelectedListener);
		}
		pager.setAdapter(adapter);
	}

	private void goToMonth(int monthIndex) {
		pager.setCurrentItem(monthIndex);
	}

	public Locale getLocale() {
		return locale;
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
		invalidate();
	}

	public void setOnDateSelected(OnDateSelectedListener dateSelectedListener) {
		this.dateSelectedListener = dateSelectedListener;
		if (adapter != null) {
			adapter.setOnDateSelectedListener(dateSelectedListener);
		}
	}
	
	public void setIntervalBackground(Date start, Date end, int resID) {
		if (adapter != null) {
			adapter.setIntervalBackgroundResId(start, end, resID);
		}
	}
	
	public void setIntervalTextColor(Date startDate, Date endDate, int textColor) {
		if (adapter != null) {
			adapter.setIntervalTextColor(startDate, endDate, textColor);
		}
	}

	protected class CalendarMonthChangedListener extends SimpleOnPageChangeListener {
		public void onPageSelected(int position) {
			updateCalendarHeader(position);
		}
	}
}
